Zhao, J & Jing, S & Jiang, L. (2018). Management of API Gateway Based on Micro-service Architecture. Journal of Physics: Conference Series. 1087. 032032. 10.1088/1742-6596/1087/3/032032.
目录 Table of Contents
阅读本论文后,主要讨论以下四点:
- 应用架构图示及分析
- 身份认证令牌选择
- 信息加载的热更新解决方案
- 分布式的流量控制
应用架构
代理服务
Nginx 接入层
- 代理流量的统一入口。
Lua 脚本集
- 支持扩展各项中间件功能,如:权限认证、负载均衡、流量控制、存储日志、请求重写和反向代理等。与“管理服务-业务逻辑层”的功能相对应。
管理服务
API 接入层
- 管理接口的统一入口。
业务逻辑层
- 支持扩展各项业务层功能,如:接口配置信息、权限认证管理、流量控制管理、系统状态监控、系统数据统计和请求重写配置等。与“代理服务-Lua 脚本集”的功能相对应。
认证中心
- 用于提供 OAuth 2 + JWT 认证功能。
注册中心
- 用于提供服务发现与服务注册功能。
持久层
Redis 集群
- 作分布式限流的计数器;
- 缓存响应请求结果。
MySQL 集群
- 主要用于存储流量控制信息。
注:作者没有进一步阐述为什么服务配置信息和流量控制信息要分开不同类型的数据库集群存储。
MongoDB 集群
- 主要用于存储服务配置信息。
身份认证
本文将采用 OAuth 2 + JWT 组合。OAuth 2 引入了认证服务器和资源服务器的概念区分,OAuth 2 协议可以携带用户信息和权限信息的特征;JWT 是包含身份信息和过期时间的加密令牌,以减少数据库的访问。两者结合使用可以实现认证和鉴权。
毕设将采用 JWT 令牌,出于简化的目的去除了 OAuth,更接近原文中所提及的 AppKeys ,也可以基本满足当前的需求。AppKeys 身份认证模式更适合开放服务的场景,它不涉及用户信息和权限信息。
信息加载
本文的处理方式是:先从 Nginx Cache 中读,再从 MongoDB 中读,否则判断为非法的请求。Nginx 是自定义网关技术的常见基石;MongoDB 作为文档型数据库在修改服务配置信息上十分方便。
毕设的处理方式是:先从 Redis 中读,再从 MySQL 中读,否则判断为非法的请求。Redis 是一个高性能的内存键值数据库,很适合用作为缓存;MySQL 作为关系型数据库,可以更好地抽象和管理服务信息、访问控制、负载均衡和租户信息等实体关系。
尽管如此,无论哪种方式都亟待去解决以下问题:
MongoDB 更新之后如何刷新 Nginx Cache ?MySQL 更新之后如何刷新 Redis ?
事实上,我们可以对这个问题进行抽象化:
已知:A 服务写多读少,流量小;B 服务只读不写,流量大;C 数据由 A 服务写入数据库,由 A 服务或 B 服务读出数据库。
问题:如何使 A 服务和 B 服务之间保证 C 数据同步且一致(请求不能直接打到底层的数据库)呢?
进行头脑风暴之后,解决的思路有:
- 管理服务同步更新代理服务:代理服务提供配置下发接口,管理服务变更时调用该接口,代理服务在内存中重新同步管理服务配置数据。缺点:代理服务和管理服务强耦合;配置下发性能损耗。
- 管理服务异步更新代理服务:代理服务开启异步定时任务,管理服务直接变更,代理服务在内存中周期同步管理服务配置数据。缺点:数据一致性较差。
- MySQL 主从复制实现读写分离:主库写从库读,主库写时要解锁,从库读时不加锁。缺点:请求直接会打到数据库,并发要求可能被满足,但比内存数据库的请求时间会长。
- 从 MySQL 同步数据至 Redis:增删改 MySQL 时,删除 Redis 对应的记录;查 Redis 时,如果命中立即返回,没有命中查 MySQL 并回写到 Redis。缺点:需要考虑缓存穿透、击穿和雪崩等问题。
- 引入 RabbitMQ 解耦:观察与订阅的模式,生产者的 MySQL 发生改动时通知消费者的 Redis 也发生改动。缺点:又引进新组件,运维成本进一步地增大。
- 使用 Consul 作为配置中心:Consul 既可以作为注册中心又可以作为配置中心,是分布式的键值型数据库。缺点:服务配置信息蕴含实体关系映射,不是配置中心的经典使用场景。
流量控制
本文中使用 Redis 充当计数器来实现限流,适用于分布式的环境。
毕设中可以采用官方原生库 golang.org/x/time/rate
或滴滴开源库 github.com/didip/tollbooth
,仅适用单机版的环境。
显然,考虑到可扩展性,网关会以集群的形式进行部署,分布式限流是更为合理的。
总结
本文提出了一种基于 Nginx + Lua 实现的微服务 API 网关的架构,在身份认证、信息加载和流量控制这三个方面为毕设工作提供了宝贵的参考。